<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue';
import { ElCard, ElRow, ElCol } from 'element-plus';
import { commandApi } from "@/api/index"
import { ElMessage } from 'element-plus';

// 数据源
const deviceState = ref(0);
const deviceAttribute = ref({
  "temperature": "",
  "humidity": "",
  "doorState": 0,
  "curtainState": 0,
  "airQuality": "",
  "ppm": "",
  "doorway": 0,
  "light": 0
});
const commandParams = ref({
  "commandName": "",
  "paraName": "",
  "paraValue": ""
});

// WebSocket连接引用
const websocket = ref(null);
// 添加重连定时器引用
const reconnectTimer = ref(null);
// 添加连接状态标识
const isConnected = ref(false);
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const websocketUrl = `${protocol}//${window.location.host}/ws/device/websocket`;

// 初始化WebSocket连接
const initWebSocket = () => {
  // 如果已经存在连接并且连接是开启状态，则直接返回
  if (websocket.value && websocket.value.readyState === WebSocket.OPEN) {
    return;
  }
  
  // 清除之前的重连定时器
  if (reconnectTimer.value) {
    clearTimeout(reconnectTimer.value);
    reconnectTimer.value = null;
  }
  
  // 创建WebSocket实例
  websocket.value = new WebSocket(websocketUrl);
  
  // 连接打开时的处理
  websocket.value.onopen = () => {
    console.log('WebSocket连接已建立');
    isConnected.value = true;
    // 获取设备状态
    getDeviceState();
    // 获取设备属性
    getDeviceAttribute();
  };
  
  // 接收消息时的处理
  websocket.value.onmessage = (event) => {
    const data = JSON.parse(event.data);
    
    // 根据消息类型更新对应数据
    if (data.type == 'deviceState') {
      deviceState.value = data.data;
    } else if (data.type == 'deviceAttribute') {
      deviceAttribute.value = data.data;
    }
  };
  
  // 连接关闭时的处理
  websocket.value.onclose = () => {
    console.log('WebSocket连接已关闭');
    isConnected.value = false;
    websocket.value = null;
    // 页面可见时才尝试重连
    if (!document.hidden) {
      reconnectTimer.value = setTimeout(() => {
        initWebSocket();
      }, 3000);
    }
  };
  
  // 连接错误时的处理
  websocket.value.onerror = (error) => {
    console.error('WebSocket连接出错:', error);
    isConnected.value = false;
    websocket.value = null;
  };
};

// 发送消息到服务器
const sendWebSocketMessage = (message) => {
  if (websocket.value && websocket.value.readyState === WebSocket.OPEN) {
    websocket.value.send(JSON.stringify(message));
  }
};

// 获取设备状态
const getDeviceState = () => {
  sendWebSocketMessage({
    action: 'getDeviceState'
  });
};

// 获取设备属性
const getDeviceAttribute = () => {
  sendWebSocketMessage({
    action: 'getDeviceAttribute'
  });
};

// 钩子函数
onMounted(() => {
  // 初始化WebSocket连接
  initWebSocket();
  
  // 监听页面可见性变化
  document.addEventListener('visibilitychange', handleVisibilityChange);
});

// 组件销毁前关闭WebSocket连接
onUnmounted(() => {
  // 移除页面可见性监听
  document.removeEventListener('visibilitychange', handleVisibilityChange);
  
  // 清除重连定时器
  if (reconnectTimer.value) {
    clearTimeout(reconnectTimer.value);
    reconnectTimer.value = null;
  }
  
  // 关闭WebSocket连接
  if (websocket.value) {
    websocket.value.close();
    websocket.value = null;
    isConnected.value = false;
  }
});

// 处理页面可见性变化
const handleVisibilityChange = () => {
  if (document.hidden) {
    // 页面隐藏时，清除重连定时器
    if (reconnectTimer.value) {
      clearTimeout(reconnectTimer.value);
      reconnectTimer.value = null;
    }
    
    // 关闭WebSocket连接
    if (websocket.value) {
      websocket.value.close();
      websocket.value = null;
      isConnected.value = false;
    }
  } else {
    // 页面显示时，重新连接WebSocket
    initWebSocket();
  }
};

//设备命令下发
//关门
const closeDoor = async () => { 
  // 判断设备是否在线
  if (!checkDeviceOnline()) {
    return;
  }

  commandParams.value = {
    "commandName": "door",
    "paraName": "control",
    "paraValue": "OFF"
  }
  const result = await commandApi(commandParams.value);
  if (result.code) {
    ElMessage.success("执行关门操作成功");
  } else { //失败
    ElMessage.error(result.msg);
  }
};
//开门
const openDoor = async () => { 
  // 判断设备是否在线
  if (!checkDeviceOnline()) {
    return;
  }

  commandParams.value = {
    "commandName": "door",
    "paraName": "control",
    "paraValue": "ON"
  }
  const result = await commandApi(commandParams.value);
  if (result.code) {
    ElMessage.success("执行开门操作成功");
  } else { //失败
    ElMessage.error(result.msg);
  }
};

//关窗帘
const closeCurtain = async () => { 
  // 判断设备是否在线
  if (!checkDeviceOnline()) {
    return;
  }

  commandParams.value = {
    "commandName": "curtain",
    "paraName": "control",
    "paraValue": "OFF"
  }
  const result = await commandApi(commandParams.value);
  if (result.code) {
    ElMessage.success("执行关窗帘操作成功");
  } else { //失败
    ElMessage.error(result.msg);
  }
};
//开窗帘
const openCurtain = async () => { 
  // 判断设备是否在线
  if (!checkDeviceOnline()) {
    return;
  }

  commandParams.value = {
    "commandName": "curtain",
    "paraName": "control",
    "paraValue": "ON"
  }
  const result = await commandApi(commandParams.value);
  if (result.code) {
    ElMessage.success("执行开窗帘操作成功");
  } else { //失败
    ElMessage.error(result.msg);
  }
};

//关灯
const closeLight = async () => { 
  // 判断设备是否在线
  if (!checkDeviceOnline()) {
    return;
  }

  commandParams.value = {
    "commandName": "light",
    "paraName": "control",
    "paraValue": "OFF"
  }
  const result = await commandApi(commandParams.value);
  if (result.code) {
    ElMessage.success("执行关灯操作成功");
  } else { //失败
    ElMessage.error(result.msg);
  }
};
//开灯
const openLight = async () => { 
  // 判断设备是否在线
  if (!checkDeviceOnline()) {
    return;
  }

  commandParams.value = {
    "commandName": "light",
    "paraName": "control",
    "paraValue": "ON"
  }
  const result = await commandApi(commandParams.value);
  if (result.code) {
    ElMessage.success("执行开灯操作成功");
  } else { //失败
    ElMessage.error(result.msg);
  }
};

// 下发命令时判断设备是否在线
const checkDeviceOnline = () => { 
  if (deviceState.value == 0) {
    ElMessage.error("设备已离线，请检查设备是否正常连接");
    return false;
  } else {
    return true;
  }
};

// 温度图标的颜色变化
const temperatureColor = computed(() => {
  if (deviceAttribute.value.temperature <= 18) {
    return '#00a0f0';
  } else if (deviceAttribute.value.temperature <= 26) {
    return 'green';
  } else if (deviceAttribute.value.temperature <= 30) {
    return 'yellow';
  } else {
    return 'red';
  }
});

</script>

<template>
  <el-row :gutter="20">
    <el-col :span="4">
      <el-card class="box-card">
        <template #header>
          <div class="card-header" align="center">
            <span>设备在线状态</span>
          </div>
        </template>
        <div class="card-content" style="min-height: 60px; min-width: 60px;">
          <p v-if="deviceState == 0"><svg-icon name="offline" size="2em" /></p>
          <p v-if="deviceState == 1"><svg-icon name="online" size="2em" /></p>
          <p>{{ deviceState == 1 ? "在线" : "离线" }}</p>
        </div>
      </el-card>  
    </el-col>
  </el-row>
  <el-row :gutter="15">
    <el-col :span="6">
      <el-card class="box-card">
        <template #header>
          <div class="card-header" align="center">
            <span>温度</span>
          </div>
        </template>
        <div class="card-content">
          <p><svg-icon name="temperature" :color="temperatureColor" size="3em" /></p>
          <p>{{ deviceAttribute.temperature }}°C</p>
        </div>
      </el-card>
    </el-col>
    <el-col :span="6">
      <el-card class="box-card">
        <template #header>
          <div class="card-header" align="center">
            <span>湿度</span>
          </div>
        </template>
        <div class="card-content">
          <p><svg-icon name="humidity" color="#23abf2" size="3em" /></p>
          <p>{{ deviceAttribute.humidity }}%</p>
        </div>
      </el-card>
    </el-col>
    <el-col :span="6">
      <el-card class="box-card">
        <template #header>
          <div class="card-header" align="center">
            <span>门状态</span>
          </div>
        </template>
        <div class="card-content">
          <p v-if="deviceAttribute.doorState == 0"><svg-icon name="door-close" color="#909399" size="2em" /></p>
          <p v-if="deviceAttribute.doorState == 1"><svg-icon name="door-open" color="green" size="2em" /></p>
          <p>{{ deviceAttribute.doorState == 0 ? '门已关' : '门已开' }}</p>
          <p>
            <el-button type="info" @click="closeDoor" plain round :disabled="deviceAttribute.doorState == 0">关门</el-button>
            <el-button type="success" @click="openDoor" plain round :disabled="deviceAttribute.doorState == 1">开门</el-button>
          </p>
        </div>
      </el-card>
    </el-col>
    <el-col :span="6">
      <el-card class="box-card">
        <template #header>
          <div class="card-header" align="center">
            <span>窗帘状态</span>
          </div>
        </template>
        <div class="card-content">
          <p v-if="deviceAttribute.curtainState == 0"><svg-icon name="curtain-close" size="2em" /></p>
          <p v-if="deviceAttribute.curtainState == 1"><svg-icon name="curtain-open" size="2em" /></p>
          <p>{{ deviceAttribute.curtainState == 0 ? '窗帘已关' : '窗帘已开' }}</p>
          <p>
            <el-button type="info" @click="closeCurtain" plain round :disabled="deviceAttribute.curtainState == 0">关窗帘</el-button>
            <el-button type="primary" @click="openCurtain" plain round :disabled="deviceAttribute.curtainState == 1">开窗帘</el-button>
          </p>
        </div>
      </el-card>
    </el-col>
  </el-row>
  <el-row :gutter="20">
    <el-col :span="6">
      <el-card class="box-card">
        <template #header>
          <div class="card-header" align="center">
            <span>空气质量</span>
          </div>
        </template>
        <div class="card-content">
          <p v-if="deviceAttribute.airQuality <= 50"><svg-icon name="air-quality-1"size="2em" /></p>
          <p v-else-if="deviceAttribute.airQuality <= 100"><svg-icon name="air-quality-2" size="2em" /></p>
          <p v-else-if="deviceAttribute.airQuality <= 150"><svg-icon name="air-quality-3"size="2em" /></p>
          <p v-else-if="deviceAttribute.airQuality <= 200"><svg-icon name="air-quality-4" size="2em" /></p>
          <p v-else-if="deviceAttribute.airQuality <= 300"><svg-icon name="air-quality-5" size="2em" /></p>
          <p v-else><svg-icon name="air-quality-6"size="2em" /></p>
          <p>{{ deviceAttribute.airQuality }}</p>
        </div>
      </el-card>
    </el-col>
    <el-col :span="6">
      <el-card class="box-card">
        <template #header>
          <div class="card-header" align="center">
            <span>空气污染平均指数</span>
          </div>
        </template>
        <div class="card-content">
          <p><svg-icon name="PPM" color="green" size="2em" /></p>
          <p>{{ deviceAttribute.ppm }}</p>
        </div>
      </el-card>
    </el-col>
    <el-col :span="6">
      <el-card class="box-card">
        <template #header>
          <div class="card-header" align="center">
            <span>门口红外识别</span>
          </div>
        </template>
        <div class="card-content">
          <p v-if="deviceAttribute.doorway == 0"><svg-icon name="IR-0" size="2em" /></p>
          <p v-if="deviceAttribute.doorway == 1"><svg-icon name="IR-1" size="2em" /></p>
          <p>{{ deviceAttribute.doorway == 0 ? '门外没人' : '门外有人' }}</p>
        </div>
      </el-card>
    </el-col>
    <el-col :span="6">
      <el-card class="box-card">
        <template #header>
          <div class="card-header" align="center">
            <span>灯状态</span>
          </div>
        </template>
        <div class="card-content">
          <p v-if="deviceAttribute.light == 0"><svg-icon name="light-close" color="#909399" size="2em" /></p>
          <p v-if="deviceAttribute.light == 1"><svg-icon name="light-open" color="#E6A23C" size="2em" /></p>
          <p>{{ deviceAttribute.light == 0 ? '灯已关' : '灯已开' }}</p>
          <p>
            <el-button type="info" @click="closeLight" plain round :disabled="deviceAttribute.light == 0">关灯</el-button>
            <el-button type="warning" @click="openLight" plain round :disabled="deviceAttribute.light == 1">开灯</el-button>
          </p>
        </div>
      </el-card>
    </el-col>
  </el-row>
</template>

<style scoped>
.el-row {
  margin-bottom: 15px;
}

.card-header {
  font-size: 18px;
  font-weight: bold;
  text-align: center;
}

.card-content {
  font-size: 16px;
  font-weight: bold;
  text-align: center;
  padding: 0px 0;
  min-height: 105px; /* 设置最小高度确保卡片对齐 */
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.card-content p:last-child {
  margin-top: 10px;
}
</style>